#include "GraphicGraph.h"

void MyApp::open_list()
{
	list.clear();

	Fl_Native_File_Chooser *fnfc = new Fl_Native_File_Chooser();
	fnfc->title("Pick a file");
	fnfc->type(Fl_Native_File_Chooser::BROWSE_FILE);
	fnfc->filter("Text\t*.txt\n"
	            "C Files\t*.{cxx,h,c}");
	fnfc->directory(".");           // default directory to use
	// Show native chooser
	switch ( fnfc->show() )
	{
	  case -1: printf("ERROR: %s\n", fnfc->errmsg());    break;  // ERROR
	  case  1: printf("CANCEL\n");                      break;  // CANCEL
	  default: printf("PICKED: %s\n", fnfc->filename()); break;  // FILE CHOSEN
	}

	cout<<"Loading adjacency list"<<endl;


	ifstream input_file (fnfc->filename());
	char temp;

	input_file>>size;
	list.resize(size);

	for(int i = 0; i < size; i++) //cycle through each room
	{
		list[i].room_number = i;
		list[i].parent = -1;
		list[i].visited = false;
		for(int j = 0; j < 4; j++)//cycle through each possible door location
		{

			input_file>>temp;

			if(temp=='1')
			{
				if(j==0)//North door
					list[i].edges.push_back(i-sqrt(size));
				else if(j==1)//East door
					list[i].edges.push_back(i+1);
				else if(j==2)//South door
					list[i].edges.push_back(i+sqrt(size));
				else//West door
					list[i].edges.push_back(i-1);
			}
		}
	}

	//print the graph to the screen
	this->redraw();
}

void MyApp::draw()
{
	//std::cout<<"Printing adj list"<<endl;

	Fl_Box::draw();
    fl_line_style(FL_SOLID, 5);



    //fl_color(45);
	for(int i = 0; i < list.size(); i++)
	{
		int x1 = (50+(100*(list[i].room_number % (int)sqrt(size))));
		int y1 = (50+(100*(list[i].room_number / (int)sqrt(size))));

		int x2 = x1 + 33;
		int x3 = x1 + 66;
		int x4 = x1 + 100;
		int xl = x1 + 50;
		int xn = x1 + 40;
		int xm = x1 + 60;

		int y2 = y1 + 33;
		int y3 = y1 + 66;
		int y4 = y1 + 100;
		int yl = y1 + 50;
		int yn = y1 + 40;
		int ym = y1 + 60;


	    fl_color(180);
		fl_line(x1,y1,x1,y4);
		fl_line(x1,y1,x4,y1);
		fl_line(x4,y1,x4,y4);
		fl_line(x1,y4,x4,y4);

		for(int j = 0; j < list[i].edges.size(); j++)
		{
		    fl_color(45);

			if(list[i].edges[j] == list[i].room_number - sqrt(size))
			{
				//cout<<"North Door"<<endl;
				fl_line(x2,y1,x3,y1);

				if(list[i].visited == true && list[i-sqrt(size)].visited == true)
				{
					fl_color(130);
					fl_line_style(FL_DASH, 3);
					fl_line(xl,y1,xl, yn);
					fl_line_style(FL_SOLID, 5);
					fl_color(45);
				}

			}
			else if(list[i].edges[j] == list[i].room_number + sqrt(size))
			{
				//cout<<"South Door"<<endl;
				fl_line(x2,y4,x3,y4);

				if(list[i].visited == true && list[i+sqrt(size)].visited == true)
				{
					fl_color(130);
					fl_line_style(FL_DASH, 3);
					fl_line(xl,ym,xl,y4);
					fl_line_style(FL_SOLID, 5);
					fl_color(45);
				}
			}
			else if(list[i].edges[j] == list[i].room_number - 1)
			{
				//cout<<"West Door"<<endl;
				fl_line(x1,y2,x1,y3);

				if(list[i].visited == true && list[i-1].visited == true)
				{
					fl_color(130);
					fl_line_style(FL_DASH, 3);
					fl_line(x1,yl,xn, yl);
					fl_line_style(FL_SOLID, 5);
					fl_color(45);
				}

			}
			else
			{
				//cout<<"East Door"<<endl;
				fl_line(x4,y2,x4,y3);

				if(list[i].visited == true && list[i+1].visited == true)
				{
					fl_color(130);
					fl_line_style(FL_DASH, 3);
					fl_line(xm,yl,x4, yl);
					fl_line_style(FL_SOLID, 5);
					fl_color(45);
				}
			}
		}

	    fl_color(200);

		char s[5];
		sprintf(s, "%d", i);

		//Room Number
		fl_draw(s,xl,yl);
		//fl_rectf(100,100,100,100);

	}
}

void MyApp::Menu_CB2()
{
        char picked[80];
        menubar->item_pathname(picked, sizeof(picked)-1);
        printf("CALLBACK: You picked '%s'\n", picked);

        // How to handle callbacks..
        if ( strcmp(picked, "File/Open") == 0 ) (this)->open_list();
        if ( strcmp(picked, "File/Quit") == 0 ) exit(0);
        if ( strcmp(picked, "File/Print") == 0 ) (this)->print_list();
        if ( strcmp(picked, "DFS/Run") == 0 ) (this)->perform_DFS();
        if ( strcmp(picked, "DFS/Print Path") == 0) (this)->redraw();
}

void MyApp::perform_DFS()
{
	if(list.empty())
		cout<<"You need to open a list"<<endl;
	else
	{
		cout<<"Performing DFS"<<endl;

		for(int i = 0; i < list.size(); i++)
			list[i].visited = false;

		DFS_visit(list[0]);

		for(int i = 0; i < list.size(); i++)
			list[i].visited = false;

		vert temp_vert = list[list.size()-1];
		vector<int> shortest_path;

		shortest_path.push_back(list.size()-1);
		while(temp_vert.parent != -1)
		{
			shortest_path.push_back(temp_vert.parent);
			temp_vert = list[temp_vert.parent];
		}

		for(int i = shortest_path.size()-1; i >= 0; i--)
		{
			list[shortest_path[i]].visited = true;
		}

	}
}

void MyApp::DFS_visit(vert & u)
{
	u.visited = true;
	for(int i = 0; i < u.edges.size(); i++)
	{
		if(list[u.edges[i]].visited==false)
		{
			DFS_visit(list[u.edges[i]]);
			list[u.edges[i]].parent = u.room_number;
		}
	}
}

void MyApp::print_list()
{
	if(list.empty())
		cout<<"You need to open a list"<<endl;
	else
	{
		for(int i = 0; i < list.size(); i++)
		{
			cout<<"Room: "<<i<<" : Doors: ";
			for(int j = 0; j < list[i].edges.size(); j++)
			{
				cout<<list[i].edges[j]<<",";
			}
			cout<<" Visited: "<<boolalpha<<list[i].visited;
			cout<<noboolalpha;
			cout<<" Parent: "<<list[i].parent;
			cout<<endl;
		}
	}
}

